package com.middlegroup.subjectpay.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.middlegroup.common.enums.ChannelCode;
import com.middlegroup.common.enums.ConfigKeyEnums;
import com.middlegroup.common.exception.ErrorMsg;
import com.middlegroup.common.model.NotifyRequest;
import com.middlegroup.common.model.SubjectpayQueryRequest;
import com.middlegroup.common.model.TransResult;
import com.middlegroup.common.utils.DateUtils;
import com.middlegroup.subjectpay.dto.BindCardDto;
import com.middlegroup.subjectpay.dto.TransRequest;
import com.middlegroup.subjectpay.entity.*;
import com.middlegroup.subjectpay.service.*;
import com.middlegroup.subjectpay.service.ucfpay.AESCoder;
import com.middlegroup.subjectpay.service.ucfpay.CallbackRequest;
import com.middlegroup.subjectpay.service.ucfpay.UcfForOnline;
import com.middlegroup.subjectpay.service.ucfpay.UcfpayConstants;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * Created by pc on 2019/1/14.
 */
@Service
@Slf4j
public class UcfpayServiceImpl implements UcfpayService {
    @Resource
    private RestTemplate restTemplate;
    @Resource
    private ThirdProtocolBindLogService thirdProtocolBindLogService;
    @Resource
    private SubjectChannelConfigService subjectChannelConfigService;
    @Resource
    private UcfpayDsBankCodeService ucfpayDsBankCodeService;
    @Resource
    private SubjectInThirdBillsService subjectInThirdBillsService;
    @Resource
    private SubjectInNotifyLogService subjectInNotifyLogService;
    @Resource
    private SubjectInBillsService subjectInBillsService;
    @Resource
    private SubjectPayNotifyUtil subjectPayNotifyUtil;

    @Override
    public TransResult bindcardApply(BindCardDto bindCardDto) {
        TransResult bindCardResult = new TransResult();
        bindCardResult.setBillNo(bindCardDto.getBillNo());
        bindCardResult.setMerchantBillNo(bindCardDto.getMerchantBillNo());
        bindCardResult.setTransStatus(0);
        bindCardResult.setMsg("绑卡申请处理中");

        String category=bindCardDto.getChannelCode().getCode();

        String merchantNo=subjectChannelConfigService.getConfigString(category, ConfigKeyEnums.MERCHANTNO.getName());
        String requestUrl=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.REQUESTURL.getName());
        String privateKey=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.PRIVATEKEY.getName());
        String publicKey=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.PUBLICKEY.getName());
        String callBackUrl=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.CALLBACKURL.getName());
        String MD5Key=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.MD5KEY.getName());

//        String merchantNo="M200006656";
//        String requestUrl="https://mapi.ucfpay.com/gateway.do";
//        String privateKey="该渠道不用这个字段值";
//        String publicKey="MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtORa9qWJIFHgM3UxhxXp9T2vbPB0CScI6l2c7t9/6bCUjZsdxx1BR0IxfOdgiW6Xl8OpBIwR/w7n0CyTBZmcAZrvOIi2wuWPe08LHQhVxUAzY4kAGCmhSlUShOW4PrikR31WqHkOBsIlPzJm0AtiboUQ5TraM1eo51LQrBI8XjF4cul7XOUVYImYTq0KgtvhI5kNywMDfj+HAC3JwiVJWAis6Hgz9Q6CTd+RnbadxgMdrzY+JMYMP9dRIIiOiafgohhiNvZQ+Nn1ul/7XFO28KS93roZCn5UG3KbweQyA7yxvyLdkou9Povw1698wY/4QRxihld2MZk1N/GcAxrvdQIDAQAB";
//        String callBackUrl="https://api.yihuabao.cn/yhb/api/1.0.0/notify/qmd/yxbUcfpayXyNotify";
//        String MD5Key="该渠道不用这个字段值";

        if(StringUtils.isBlank(requestUrl) || StringUtils.isBlank(merchantNo) || StringUtils.isBlank(privateKey) || StringUtils.isBlank(publicKey) || StringUtils.isBlank(callBackUrl) || StringUtils.isBlank(MD5Key)){
            bindCardResult.setTransStatus(2);
            bindCardResult.setMsg(ErrorMsg.INCOMPLETE_CONFIG_INFO);
            return bindCardResult;
        }

        Map<String,String>  params = this.createHeadParams("REQ_CONTRACT_APPLY",merchantNo);
        //data加密 //获取加密的业务数据map集合
        Map<String,String> dataParams  = this.getBindCardEncryptData(bindCardDto);
        //对业务数据进行加密
        String data = this.encryptData(dataParams,publicKey).toString();
        params.put("data",data);
        //对头、业务数据进行签名
        String signData = this.signData(params,publicKey).toString();
        params.put("sign",signData);

        MultiValueMap<String, String> postParameters = new LinkedMultiValueMap<String, String>();
        for(String key : params.keySet()){
            postParameters.add(key,params.get(key));
        }

        ThirdProtocolBindLog thirdProtocolBindLog=new ThirdProtocolBindLog();
        thirdProtocolBindLog.setSubjectCode(bindCardDto.getSubjectCode());
        thirdProtocolBindLog.setMerchantBillNo(bindCardDto.getMerchantBillNo());
        thirdProtocolBindLog.setBillNo(bindCardDto.getBillNo());
        thirdProtocolBindLog.setStatus(0);
        thirdProtocolBindLog.setRequestUrl(requestUrl);
        thirdProtocolBindLog.setRequestText(JSON.toJSONString(params));
        thirdProtocolBindLog.setBeginTime(System.currentTimeMillis());
        thirdProtocolBindLog.setServiceType(bindCardDto.getServiceType());

        String str = null;
        try {
            str = restTemplate.postForObject(requestUrl,postParameters,String.class);
            str = AESCoder.decrypt(str, publicKey);
        } catch (Exception e) {
            log.error("调用先锋协议绑卡申请接口异常,billNo:{},error:{}",bindCardDto.getBillNo(),e);
            bindCardResult.setMsg(ErrorMsg.PAY_INTERFACE_CALL_FAIL);
        }

        thirdProtocolBindLog.setResponseText((StringUtils.isNotBlank(str) && str.length()>4000)?str.substring(0,4000):str);
        thirdProtocolBindLog.setEndTime(System.currentTimeMillis());

        if (StringUtils.isBlank(str)) {
            //默认绑卡处理中
            log.error("调用先锋协议支付绑卡申请接口返回空,billNo:{}",bindCardDto.getBillNo());
            bindCardResult.setMsg(ErrorMsg.PAY_INTERFACE_RETURN_BLANK);
        }else {
            JSONObject jsonObject = JSON.parseObject(str);
            String result_msg = jsonObject.getString("resMessage");
            String status = jsonObject.getString("status");

            bindCardResult.setMsg(result_msg);

            //以status为准来判断订单状态
            if (StringUtils.isNotBlank(status)) {
                if (StringUtils.equals(UcfpayConstants.UCF_PAY_STATUS_SUCCESS, status)) {
                    //绑卡请求成功
                    bindCardResult.setTransStatus(1);
                    thirdProtocolBindLog.setStatus(1);
                } else if (StringUtils.equals(UcfpayConstants.UCF_PAY_STATUS_PROCESSING, status)) {
                    //绑卡请求成功
                    bindCardResult.setTransStatus(1);
                    thirdProtocolBindLog.setStatus(1);
                } else if (StringUtils.equals(UcfpayConstants.UCF_PAY_STATUS_FAILURE, status)) {
                    //绑卡请求失败
                    bindCardResult.setTransStatus(2);
                    thirdProtocolBindLog.setStatus(2);
                }
            } else {
                //绑卡请求失败
                bindCardResult.setTransStatus(2);
                thirdProtocolBindLog.setStatus(2);
            }
        }

        try {
            thirdProtocolBindLogService.insert(thirdProtocolBindLog);
        } catch (Exception e) {
            log.error("插入协议绑卡日志表异常,billNo:{},error:{}",bindCardDto.getBillNo(),e);
        }

        return bindCardResult;
    }

    @Override
    public TransResult bindcardConfirm(BindCardDto bindCardDto) {
        TransResult bindCardResult = new TransResult();
        bindCardResult.setBillNo(bindCardDto.getBillNo());
        bindCardResult.setMerchantBillNo(bindCardDto.getMerchantBillNo());
        bindCardResult.setTransStatus(0);
        bindCardResult.setMsg("绑卡确认处理中");

        String category=bindCardDto.getChannelCode().getCode();

        String merchantNo=subjectChannelConfigService.getConfigString(category, ConfigKeyEnums.MERCHANTNO.getName());
        String requestUrl=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.REQUESTURL.getName());
        String privateKey=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.PRIVATEKEY.getName());
        String publicKey=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.PUBLICKEY.getName());
        String callBackUrl=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.CALLBACKURL.getName());
        String MD5Key=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.MD5KEY.getName());

//        String merchantNo="M200006656";
//        String requestUrl="https://mapi.ucfpay.com/gateway.do";
//        String privateKey="该渠道不用这个字段值";
//        String publicKey="MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtORa9qWJIFHgM3UxhxXp9T2vbPB0CScI6l2c7t9/6bCUjZsdxx1BR0IxfOdgiW6Xl8OpBIwR/w7n0CyTBZmcAZrvOIi2wuWPe08LHQhVxUAzY4kAGCmhSlUShOW4PrikR31WqHkOBsIlPzJm0AtiboUQ5TraM1eo51LQrBI8XjF4cul7XOUVYImYTq0KgtvhI5kNywMDfj+HAC3JwiVJWAis6Hgz9Q6CTd+RnbadxgMdrzY+JMYMP9dRIIiOiafgohhiNvZQ+Nn1ul/7XFO28KS93roZCn5UG3KbweQyA7yxvyLdkou9Povw1698wY/4QRxihld2MZk1N/GcAxrvdQIDAQAB";
//        String callBackUrl="https://api.yihuabao.cn/yhb/api/1.0.0/notify/qmd/yxbUcfpayXyNotify";
//        String MD5Key="该渠道不用这个字段值";

        if(StringUtils.isBlank(requestUrl) || StringUtils.isBlank(merchantNo) || StringUtils.isBlank(privateKey) || StringUtils.isBlank(publicKey) || StringUtils.isBlank(callBackUrl) || StringUtils.isBlank(MD5Key)){
            bindCardResult.setTransStatus(2);
            bindCardResult.setMsg(ErrorMsg.INCOMPLETE_CONFIG_INFO);
            return bindCardResult;
        }

        Map<String,String>  params = this.createHeadParams("REQ_CONTRACT_CONFIRM",merchantNo);
        //data加密 //获取加密的业务数据map集合
        Map<String, String> pdata = new LinkedHashMap<>();
        pdata.put("merchantNo", bindCardDto.getBillNo());
        pdata.put("checkCode", bindCardDto.getSmsCode());
        //对业务数据进行加密
        String data = this.encryptData(pdata,publicKey).toString();
        params.put("data",data);
        //对头、业务数据进行签名
        String signData = this.signData(params,publicKey).toString();
        params.put("sign",signData);

        MultiValueMap<String, String> postParameters = new LinkedMultiValueMap<String, String>();
        for(String key : params.keySet()){
            postParameters.add(key,params.get(key));
        }

        ThirdProtocolBindLog thirdProtocolBindLog=new ThirdProtocolBindLog();
        thirdProtocolBindLog.setSubjectCode(bindCardDto.getSubjectCode());
        thirdProtocolBindLog.setMerchantBillNo(bindCardDto.getMerchantBillNo());
        thirdProtocolBindLog.setBillNo(bindCardDto.getBillNo());
        thirdProtocolBindLog.setStatus(0);
        thirdProtocolBindLog.setRequestUrl(requestUrl);
        thirdProtocolBindLog.setRequestText(JSON.toJSONString(params));
        thirdProtocolBindLog.setBeginTime(System.currentTimeMillis());
        thirdProtocolBindLog.setServiceType(bindCardDto.getServiceType());

        String str = null;
        try {
            str = restTemplate.postForObject(requestUrl,postParameters,String.class);
            str = AESCoder.decrypt(str, publicKey);
        } catch (Exception e) {
            log.error("调用先锋协议绑卡确认接口异常,billNo:{},error:{}",bindCardDto.getBillNo(),e);
            bindCardResult.setMsg(ErrorMsg.PAY_INTERFACE_CALL_FAIL);
        }

        thirdProtocolBindLog.setResponseText((StringUtils.isNotBlank(str) && str.length()>4000)?str.substring(0,4000):str);
        thirdProtocolBindLog.setEndTime(System.currentTimeMillis());

        if (StringUtils.isBlank(str)) {
            //默认绑卡处理中
            log.error("调用先锋协议支付绑卡接口返回空,billNo:{}",bindCardDto.getBillNo());
            bindCardResult.setMsg(ErrorMsg.PAY_INTERFACE_RETURN_BLANK);
        }else {
            JSONObject jsonObject = JSON.parseObject(str);
            String result_code = jsonObject.getString("resCode");
            String result_msg = jsonObject.getString("resMessage");
            //状态
            String status = jsonObject.getString("status");
            //签约号
            String contractNo = jsonObject.getString("contractNo");

            if(StringUtils.equals(result_code,"20005")){
                //短信校验失败（通用的错误原因）
                bindCardResult.setMsg(ErrorMsg.SMSCODE_FAIL);
            }else {
                bindCardResult.setMsg(result_msg);
            }

            //以status为准来判断订单状态
            if (StringUtils.isNotBlank(status)) {
                if (StringUtils.equals(UcfpayConstants.UCF_PAY_STATUS_SUCCESS, status) && StringUtils.isNotBlank(contractNo)) {
                    //绑卡确认成功成功
                    bindCardResult.setTransStatus(1);
                    thirdProtocolBindLog.setStatus(1);
                } else if (StringUtils.equals(UcfpayConstants.UCF_PAY_STATUS_PROCESSING, status) || (StringUtils.equals(UcfpayConstants.UCF_PAY_STATUS_SUCCESS,status) && StringUtils.isBlank(contractNo))) {
                    //绑卡确认处理中
                    bindCardResult.setTransStatus(0);
                    thirdProtocolBindLog.setStatus(0);
                } else if (StringUtils.equals(UcfpayConstants.UCF_PAY_STATUS_FAILURE, status) ) {
                    //失败
                    bindCardResult.setTransStatus(2);
                    thirdProtocolBindLog.setStatus(2);
                }
            } else {
                if(StringUtils.equals("00000",result_code)){
                    //绑卡确认处理中
                    bindCardResult.setTransStatus(0);
                    thirdProtocolBindLog.setStatus(0);
                }else {
                    //失败
                    bindCardResult.setTransStatus(2);
                    thirdProtocolBindLog.setStatus(2);
                }
            }
        }

        try {
            thirdProtocolBindLogService.insert(thirdProtocolBindLog);
        } catch (Exception e) {
            log.error("插入协议绑卡日志表异常,billNo:{},error:{}",bindCardDto.getBillNo(),e);
        }

        return bindCardResult;
    }

    @Override
    public TransResult reSendSms(BindCardDto bindCardDto) {
        TransResult bindCardResult = new TransResult();
        bindCardResult.setBillNo(bindCardDto.getBillNo());
        bindCardResult.setMerchantBillNo(bindCardDto.getMerchantBillNo());
        bindCardResult.setTransStatus(0);
        bindCardResult.setMsg("绑卡重发短信验证码处理中");

        String category=bindCardDto.getChannelCode().getCode();

        String merchantNo=subjectChannelConfigService.getConfigString(category, ConfigKeyEnums.MERCHANTNO.getName());
        String requestUrl=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.REQUESTURL.getName());
        String privateKey=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.PRIVATEKEY.getName());
        String publicKey=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.PUBLICKEY.getName());
        String callBackUrl=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.CALLBACKURL.getName());
        String MD5Key=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.MD5KEY.getName());

//        String merchantNo="M200006656";
//        String requestUrl="https://mapi.ucfpay.com/gateway.do";
//        String privateKey="该渠道不用这个字段值";
//        String publicKey="MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtORa9qWJIFHgM3UxhxXp9T2vbPB0CScI6l2c7t9/6bCUjZsdxx1BR0IxfOdgiW6Xl8OpBIwR/w7n0CyTBZmcAZrvOIi2wuWPe08LHQhVxUAzY4kAGCmhSlUShOW4PrikR31WqHkOBsIlPzJm0AtiboUQ5TraM1eo51LQrBI8XjF4cul7XOUVYImYTq0KgtvhI5kNywMDfj+HAC3JwiVJWAis6Hgz9Q6CTd+RnbadxgMdrzY+JMYMP9dRIIiOiafgohhiNvZQ+Nn1ul/7XFO28KS93roZCn5UG3KbweQyA7yxvyLdkou9Povw1698wY/4QRxihld2MZk1N/GcAxrvdQIDAQAB";
//        String callBackUrl="https://api.yihuabao.cn/yhb/api/1.0.0/notify/qmd/yxbUcfpayXyNotify";
//        String MD5Key="该渠道不用这个字段值";

        if(StringUtils.isBlank(requestUrl) || StringUtils.isBlank(merchantNo) || StringUtils.isBlank(privateKey) || StringUtils.isBlank(publicKey) || StringUtils.isBlank(callBackUrl) || StringUtils.isBlank(MD5Key)){
            bindCardResult.setTransStatus(2);
            bindCardResult.setMsg(ErrorMsg.INCOMPLETE_CONFIG_INFO);
            return bindCardResult;
        }

        Map<String,String>  params = this.createHeadParams("REQ_CONTRACT_RESEND",merchantNo);
        params.put("merchantNo",bindCardDto.getBillNo());
        //对头、业务数据进行签名
        String signData = this.signData(params,publicKey).toString();
        params.put("sign",signData);

        MultiValueMap<String, String> postParameters = new LinkedMultiValueMap<String, String>();
        for(String key : params.keySet()){
            postParameters.add(key,params.get(key));
        }

        ThirdProtocolBindLog thirdProtocolBindLog=new ThirdProtocolBindLog();
        thirdProtocolBindLog.setSubjectCode(bindCardDto.getSubjectCode());
        thirdProtocolBindLog.setMerchantBillNo(bindCardDto.getMerchantBillNo());
        thirdProtocolBindLog.setBillNo(bindCardDto.getBillNo());
        thirdProtocolBindLog.setStatus(0);
        thirdProtocolBindLog.setRequestUrl(requestUrl);
        thirdProtocolBindLog.setRequestText(JSON.toJSONString(params));
        thirdProtocolBindLog.setBeginTime(System.currentTimeMillis());
        thirdProtocolBindLog.setServiceType(bindCardDto.getServiceType());

        String str = null;
        try {
            str = restTemplate.postForObject(requestUrl,postParameters,String.class);
            str = AESCoder.decrypt(str, publicKey);
        } catch (Exception e) {
            log.error("调用先锋协议绑卡重发短信验证码接口异常,billNo:{},error:{}",bindCardDto.getBillNo(),e);
            bindCardResult.setMsg(ErrorMsg.PAY_INTERFACE_CALL_FAIL);
        }

        thirdProtocolBindLog.setResponseText((StringUtils.isNotBlank(str) && str.length()>4000)?str.substring(0,4000):str);
        thirdProtocolBindLog.setEndTime(System.currentTimeMillis());

        if (StringUtils.isBlank(str)) {
            //默认绑卡处理中
            log.error("调用先锋协议支付重发短信验证码接口返回空,billNo:{}",bindCardDto.getBillNo());
            bindCardResult.setMsg(ErrorMsg.PAY_INTERFACE_RETURN_BLANK);
        }else {
            JSONObject jsonObject = JSON.parseObject(str);
            String result_msg = jsonObject.getString("resMessage");
            String result_code = jsonObject.getString("resCode");

            bindCardResult.setMsg(result_msg);

            //以status为准来判断订单状态
            if(StringUtils.isNotBlank(result_code)){
                if(StringUtils.equals("00000",result_code)){
                    //短信发送成功
                    bindCardResult.setTransStatus(1);
                    thirdProtocolBindLog.setStatus(1);
                }else{
                    bindCardResult.setTransStatus(2);
                    thirdProtocolBindLog.setStatus(2);
                }
            }else{
                bindCardResult.setTransStatus(2);
                thirdProtocolBindLog.setStatus(2);
                if(StringUtils.isBlank(result_msg)){
                    bindCardResult.setMsg("调用先锋支付重发短信接口失败,详见应答码！");
                }
            }
        }

        try {
            thirdProtocolBindLogService.insert(thirdProtocolBindLog);
        } catch (Exception e) {
            log.error("插入协议绑卡日志表异常,billNo:{},error:{}",bindCardDto.getBillNo(),e);
        }

        return bindCardResult;
    }

    @Override
    public TransResult protocolPay(TransRequest request) {
        TransResult transResult = new TransResult();
        transResult.setBillNo(request.getBillNo());
        transResult.setMerchantBillNo(request.getMerchantBillNo());
        transResult.setAmount(request.getAmount());
        transResult.setTransStatus(0);
        transResult.setTransTime(System.currentTimeMillis());

        String category=request.getChannelCode().getCode();

        String merchantNo=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.MERCHANTNO.getName());
        String requestUrl=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.REQUESTURL.getName());
        String privateKey=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.PRIVATEKEY.getName());
        String publicKey=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.PUBLICKEY.getName());
        String callBackUrl=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.CALLBACKURL.getName());
        String MD5Key=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.MD5KEY.getName());

        if(StringUtils.isBlank(requestUrl) || StringUtils.isBlank(merchantNo) || StringUtils.isBlank(privateKey) || StringUtils.isBlank(publicKey) || StringUtils.isBlank(callBackUrl) || StringUtils.isBlank(MD5Key)){
            transResult.setTransStatus(2);
            transResult.setMsg(ErrorMsg.INCOMPLETE_CONFIG_INFO);
            return transResult;
        }

        Map<String,String>  params = this.createHeadParams("REQ_PROTOCOL_PAY_NS",merchantNo);
        //data加密 //获取加密的业务数据map集合
        Map<String,String> dataParams  = this.getProtocolPayEncryptData(request,callBackUrl);
        //对业务数据进行加密
        String data = this.encryptData(dataParams,publicKey).toString();
        params.put("data",data);
        //对头、业务数据进行签名
        String signData = this.signData(params,publicKey).toString();
        params.put("sign",signData);

        MultiValueMap<String, String> postParameters = new LinkedMultiValueMap<String, String>();
        for(String key : params.keySet()){
            postParameters.add(key,params.get(key));
        }

        SubjectInThirdBills subjectInThirdBills=new SubjectInThirdBills();
        subjectInThirdBills.setSubjectCode(request.getSubjectCode());
        subjectInThirdBills.setMerchantBillNo(request.getMerchantBillNo());
        subjectInThirdBills.setBillNo(request.getBillNo());
        subjectInThirdBills.setStatus(0);
        subjectInThirdBills.setAmount(request.getAmount());
        subjectInThirdBills.setRequestUrl(requestUrl);
        subjectInThirdBills.setRequestText(JSON.toJSONString(postParameters));
        subjectInThirdBills.setBeginTime(System.currentTimeMillis());
        subjectInThirdBills.setServiceType(request.getServiceType());

        String str = null;
        try {
            str = restTemplate.postForObject(requestUrl,postParameters,String.class);
            str = AESCoder.decrypt(str, publicKey);
        } catch (Exception e) {
            log.error("调用先锋协议支付接口异常,billNo:{},error:{}",request.getBillNo(),e);
            transResult.setMsg(ErrorMsg.PAY_INTERFACE_CALL_FAIL);
        }

        subjectInThirdBills.setResponseText((StringUtils.isNotBlank(str) && str.length()>4000)?str.substring(0,4000):str);
        subjectInThirdBills.setEndTime(System.currentTimeMillis());

        if (StringUtils.isBlank(str)) {
            //默认交易处理中
            log.error("调用先锋协议接口返回空,billNo:{}",request.getBillNo());
            transResult.setMsg(ErrorMsg.PAY_INTERFACE_RETURN_BLANK);
        }else {
            JSONObject jsonObject = JSON.parseObject(str);
            String result_code = jsonObject.getString("resCode");
            String result_msg = jsonObject.getString("resMessage");
            String trans_no = jsonObject.getString("tradeNo");
            String status = jsonObject.getString("status");
            //交易完成时间
            String tradeTime = jsonObject.getString("tradeTime");

            if(StringUtils.isNotBlank(tradeTime)){
                transResult.setTransTime(DateUtils.convert(tradeTime,DateUtils.DATE_TIMESTAMP_SHORT_FORMAT).getTime());
            }else{
                transResult.setTransTime(System.currentTimeMillis());
            }
            transResult.setTransNo(trans_no);
            transResult.setMsg(result_msg);

            //以status为准来判断订单状态
            if (StringUtils.isNotBlank(status)) {
                if (StringUtils.equals(UcfpayConstants.UCF_PAY_STATUS_SUCCESS, status)) {
                    //交易成功
                    transResult.setTransStatus(1);
                    subjectInThirdBills.setStatus(1);
                } else if (StringUtils.equals(UcfpayConstants.UCF_PAY_STATUS_PROCESSING, status)) {
                    //处理中
                    transResult.setTransStatus(0);
                    subjectInThirdBills.setStatus(0);
                } else if (StringUtils.equals(UcfpayConstants.UCF_PAY_STATUS_FAILURE, status)) {
                    //失败
                    transResult.setTransStatus(2);
                    subjectInThirdBills.setStatus(2);
                }
            } else {
                if(StringUtils.equals("00000",result_code)){
                    transResult.setTransStatus(0);
                    subjectInThirdBills.setStatus(0);
                }else{
                    transResult.setTransStatus(2);
                    subjectInThirdBills.setStatus(2);
                }
            }
        }

        try {
            subjectInThirdBillsService.insert(subjectInThirdBills);
        } catch (Exception e) {
            log.error("插入第三方订单表异常,billNo:{},error:{}",request.getBillNo(),e);
        }

        return transResult;
    }

    @Override
    public TransResult protocolPayQuery(SubjectpayQueryRequest request) {
        TransResult transResult = new TransResult();
        transResult.setBillNo(request.getBillNo());
        transResult.setMerchantBillNo(request.getMerchantBillNo());
        transResult.setAmount(request.getAmount());
        transResult.setTransStatus(0);
        transResult.setTransTime(System.currentTimeMillis());

        String category=request.getChannelCode();

        String merchantNo=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.MERCHANTNO.getName());
        String requestUrl=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.REQUESTURL.getName());
        String privateKey=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.PRIVATEKEY.getName());
        String publicKey=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.PUBLICKEY.getName());
        String callBackUrl=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.CALLBACKURL.getName());
        String MD5Key=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.MD5KEY.getName());

        if(StringUtils.isBlank(requestUrl) || StringUtils.isBlank(merchantNo) || StringUtils.isBlank(privateKey) || StringUtils.isBlank(publicKey) || StringUtils.isBlank(callBackUrl) || StringUtils.isBlank(MD5Key)){
            transResult.setTransStatus(2);
            transResult.setMsg(ErrorMsg.INCOMPLETE_CONFIG_INFO);
            return transResult;
        }

        Map<String,String>  params = this.createHeadParams("REQ_PROTOCOL_QUERY_BY_ID",merchantNo);
        params.put("merchantNo",request.getBillNo());
        //对头、业务数据进行签名
        String signData = this.signData(params,publicKey).toString();
        params.put("sign",signData);

        MultiValueMap<String, String> postParameters = new LinkedMultiValueMap<String, String>();
        for(String key : params.keySet()){
            postParameters.add(key,params.get(key));
        }

        SubjectInThirdBills subjectInThirdBills=new SubjectInThirdBills();
        subjectInThirdBills.setSubjectCode(request.getSubjectCode());
        subjectInThirdBills.setMerchantBillNo(request.getMerchantBillNo());
        subjectInThirdBills.setBillNo(request.getBillNo());
        subjectInThirdBills.setStatus(0);
        subjectInThirdBills.setAmount(request.getAmount());
        subjectInThirdBills.setRequestUrl(requestUrl);
        subjectInThirdBills.setRequestText(JSON.toJSONString(postParameters));
        subjectInThirdBills.setBeginTime(System.currentTimeMillis());
        subjectInThirdBills.setServiceType(request.getServiceType());

        String str = null;
        try {
            str = restTemplate.postForObject(requestUrl,postParameters,String.class);
            str = AESCoder.decrypt(str, publicKey);
        } catch (Exception e) {
            log.error("调用先锋协议支付查询接口异常,billNo:{},error:{}",request.getBillNo(),e);
            transResult.setMsg(ErrorMsg.PAY_INTERFACE_CALL_FAIL);
        }

        subjectInThirdBills.setResponseText((StringUtils.isNotBlank(str) && str.length()>4000)?str.substring(0,4000):str);
        subjectInThirdBills.setEndTime(System.currentTimeMillis());

        if (StringUtils.isBlank(str)) {
            //默认交易处理中
            log.error("调用先锋支付协议支付查询接口返回空,billNo:{}",request.getBillNo());
            transResult.setMsg(ErrorMsg.PAY_INTERFACE_RETURN_BLANK);
        }else {
            JSONObject jsonObject = JSON.parseObject(str);
            String result_code = jsonObject.getString("resCode");
            String result_msg = jsonObject.getString("resMessage");
            String trans_no = jsonObject.getString("tradeNo");
            String status = jsonObject.getString("status");
            //交易完成时间
            String tradeTime = jsonObject.getString("tradeTime");

            if(StringUtils.isNotBlank(tradeTime)){
                transResult.setTransTime(DateUtils.convert(tradeTime,DateUtils.DATE_TIMESTAMP_SHORT_FORMAT).getTime());
            }else{
                transResult.setTransTime(System.currentTimeMillis());
            }
            transResult.setTransNo(trans_no);
            transResult.setMsg(result_msg);

            //以status为准来判断订单状态
            if (StringUtils.isNotBlank(status)) {
                if (StringUtils.equals(UcfpayConstants.UCF_PAY_STATUS_SUCCESS, status)) {
                    //交易成功
                    transResult.setTransStatus(1);
                    subjectInThirdBills.setStatus(1);
                } else if (StringUtils.equals(UcfpayConstants.UCF_PAY_STATUS_PROCESSING, status)) {
                    //处理中
                    transResult.setTransStatus(0);
                    subjectInThirdBills.setStatus(0);
                } else if (StringUtils.equals(UcfpayConstants.UCF_PAY_STATUS_FAILURE, status)) {
                    //失败
                    transResult.setTransStatus(2);
                    subjectInThirdBills.setStatus(2);
                }
            } else {
                if(StringUtils.equals("00000",result_code)){
                    transResult.setTransStatus(0);
                    subjectInThirdBills.setStatus(0);
                }else{
                    transResult.setTransStatus(2);
                    subjectInThirdBills.setStatus(2);
                }
            }
        }

        try {
            subjectInThirdBillsService.insert(subjectInThirdBills);
        } catch (Exception e) {
            log.error("先锋协议支付插入第三方订单表异常,billNo:{},error:{}",request.getBillNo(),e);
        }

        return transResult;
    }

    @Override
    public TransResult bindcardQuery(SubjectpayQueryRequest request) {
        TransResult transResult = new TransResult();
        transResult.setBillNo(request.getBillNo());
        transResult.setMerchantBillNo(request.getMerchantBillNo());
        transResult.setAmount(request.getAmount());
        transResult.setTransStatus(0);
        transResult.setTransTime(System.currentTimeMillis());

        String category=request.getChannelCode();

        String merchantNo=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.MERCHANTNO.getName());
        String requestUrl=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.REQUESTURL.getName());
        String privateKey=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.PRIVATEKEY.getName());
        String publicKey=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.PUBLICKEY.getName());
        String callBackUrl=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.CALLBACKURL.getName());
        String MD5Key=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.MD5KEY.getName());

        if(StringUtils.isBlank(requestUrl) || StringUtils.isBlank(merchantNo) || StringUtils.isBlank(privateKey) || StringUtils.isBlank(publicKey) || StringUtils.isBlank(callBackUrl) || StringUtils.isBlank(MD5Key)){
            transResult.setTransStatus(2);
            transResult.setMsg(ErrorMsg.INCOMPLETE_CONFIG_INFO);
            return transResult;
        }

        Map<String,String>  params = this.createHeadParams("REQ_CONTRACT_QUERY",merchantNo);
        params.put("merchantNo",request.getBillNo());
        //对头、业务数据进行签名
        String signData = this.signData(params,publicKey).toString();
        params.put("sign",signData);

        MultiValueMap<String, String> postParameters = new LinkedMultiValueMap<String, String>();
        for(String key : params.keySet()){
            postParameters.add(key,params.get(key));
        }

        SubjectInThirdBills subjectInThirdBills=new SubjectInThirdBills();
        subjectInThirdBills.setSubjectCode(request.getSubjectCode());
        subjectInThirdBills.setMerchantBillNo(request.getMerchantBillNo());
        subjectInThirdBills.setBillNo(request.getBillNo());
        subjectInThirdBills.setStatus(0);
        subjectInThirdBills.setAmount(request.getAmount());
        subjectInThirdBills.setRequestUrl(requestUrl);
        subjectInThirdBills.setRequestText(JSON.toJSONString(postParameters));
        subjectInThirdBills.setBeginTime(System.currentTimeMillis());
        subjectInThirdBills.setServiceType(request.getServiceType());

        String str = null;
        try {
            str = restTemplate.postForObject(requestUrl,postParameters,String.class);
            str = AESCoder.decrypt(str, publicKey);
        } catch (Exception e) {
            log.error("调用先锋协议支付绑卡查询接口异常,billNo:{},error:{}",request.getBillNo(),e);
            transResult.setMsg(ErrorMsg.PAY_INTERFACE_CALL_FAIL);
        }

        subjectInThirdBills.setResponseText((StringUtils.isNotBlank(str) && str.length()>4000)?str.substring(0,4000):str);
        subjectInThirdBills.setEndTime(System.currentTimeMillis());

        if (StringUtils.isBlank(str)) {
            //默认交易处理中
            log.error("调用先锋支付协议支付绑卡查询接口返回空,billNo:{}",request.getBillNo());
            transResult.setMsg(ErrorMsg.PAY_INTERFACE_RETURN_BLANK);
        }else {
            JSONObject jsonObject = JSON.parseObject(str);
            String result_code = jsonObject.getString("resCode");
            String result_msg = jsonObject.getString("resMessage");
            String trans_no = jsonObject.getString("tradeNo");
            String status = jsonObject.getString("status");
            //交易完成时间
            String tradeTime = jsonObject.getString("tradeTime");
            //签约号
            String contractNo = jsonObject.getString("contractNo");

            if(StringUtils.isNotBlank(tradeTime)){
                transResult.setTransTime(DateUtils.convert(tradeTime,DateUtils.DATE_TIMESTAMP_SHORT_FORMAT).getTime());
            }else{
                transResult.setTransTime(System.currentTimeMillis());
            }
            transResult.setTransNo(trans_no);
            transResult.setMsg(result_msg);

            //以status为准来判断绑卡状态
            if (StringUtils.isNotBlank(status)) {
                if (StringUtils.equals(UcfpayConstants.UCF_PAY_STATUS_SUCCESS, status)) {
                    //交易成功
                    transResult.setTransStatus(1);
                    subjectInThirdBills.setStatus(1);
                    //设置好协议号返回
                    transResult.setProtocolNo(contractNo);
                } else if (StringUtils.equals(UcfpayConstants.UCF_PAY_STATUS_PROCESSING, status)) {
                    //处理中
                    transResult.setTransStatus(0);
                    subjectInThirdBills.setStatus(0);
                } else if (StringUtils.equals(UcfpayConstants.UCF_PAY_STATUS_FAILURE, status)) {
                    //失败
                    transResult.setTransStatus(2);
                    subjectInThirdBills.setStatus(2);
                }
            } else {
                if(StringUtils.equals("00000",result_code)){
                    transResult.setTransStatus(0);
                    subjectInThirdBills.setStatus(0);
                }else{
                    transResult.setTransStatus(2);
                    subjectInThirdBills.setStatus(2);
                }
            }
        }

        try {
            subjectInThirdBillsService.insert(subjectInThirdBills);
        } catch (Exception e) {
            log.error("先锋协议支付插入第三方订单表异常,billNo:{},error:{}",request.getBillNo(),e);
        }

        return transResult;
    }

    @Override
    public String protocolPayNotify(CallbackRequest request) {
        String result ="";

        //记录回调原始数据
        SubjectInNotifyLog subjectInNotifyLog = new SubjectInNotifyLog();
        subjectInNotifyLog.setCallbackText(JSONObject.toJSONString(request));
        //默认回调处理状态为处理中
        subjectInNotifyLog.setStatus(0);
        //默认订单交易状态为处理中
        subjectInNotifyLog.setTransStatus(0);
        subjectInNotifyLog.setCallbackText(request.getData());
        subjectInNotifyLog.setMsg("回调处理中");
        boolean rt = subjectInNotifyLogService.insert(subjectInNotifyLog);
        if (!rt){
            log.error("插入回调日志表失败,request:{}",request);
            return result;
        }

        String publicKey=subjectChannelConfigService.getConfigString(ChannelCode.CH3333331.getCode(),ConfigKeyEnums.PUBLICKEY.getName());

        String enData = request.getData();
        String dataStr = null;
        try {
            dataStr = AESCoder.decrypt(enData , publicKey);
        }catch (Exception e){
            log.error("先锋协议支付回调数据前为："+ request.getData() +" 】 【处理后为："+enData);
            log.error("先锋协议支付数据解密时出错",e);
        }

        subjectInNotifyLog.setCallbackText(dataStr);

        JSONObject data = JSONObject.parseObject(dataStr);
        //保存签名值
        String signValue = "";
        //保存参与验签字段
        Map<String,String> signParameters = new HashMap<String,String>();
        if(null != data){
            Iterator iterator = data.keySet().iterator();
            while(iterator.hasNext()){
                String key = iterator.next().toString();
                String value = data.getString(key);
                if(StringUtils.equals( UcfpayConstants.SIGN,key)){
                    signValue = value;
                }else{
                    signParameters.put(key, value);
                }
            }

        }
        boolean verifyResult = false;
        try{
            verifyResult = UcfForOnline.verify(publicKey, UcfpayConstants.SIGN, signValue, signParameters,  UcfpayConstants.SECID);
        }catch (Exception e){
            log.error("调用先锋协议支付类库中验签方法异常！");
        }

        if(verifyResult){
            String resCode = signParameters.get("resCode");
            String resMessage = signParameters.get("resMessage");
            //订单支付状态：S成功，F 失败
            String status = signParameters.get("status");
            String transNo = signParameters.get("tradeNo");
            String billNo = signParameters.get("merchantNo");
            //交易完成时间 要转换
            String tradeTime = signParameters.get("tradeTime");

            //查询回调对应的订单信息
            SubjectInBills subjectInBillsFind = new SubjectInBills();
            subjectInBillsFind.setBillNo(billNo);
            SubjectInBills subjectInBills = subjectInBillsService.getLastOneInBills(subjectInBillsFind);
            if(null==subjectInBills){
                log.error("未查询到该笔订单,request:{}",request);
                return result;
            }
            subjectInNotifyLog.setBillNo(billNo);
            subjectInNotifyLog.setSubjectCode(subjectInBills.getSubjectCode());
            subjectInNotifyLog.setMerchantBillNo(subjectInBills.getMerchantBillNo());
            subjectInNotifyLog.setStatus(1);
            subjectInNotifyLog.setTransNo(transNo);
            subjectInNotifyLog.setMsg(resMessage);

            //转发到支付中台的回调对象
            NotifyRequest notifyRequest=new NotifyRequest();
            notifyRequest.setMerchantBillNo(subjectInBills.getMerchantBillNo());
            notifyRequest.setBillNo(subjectInBills.getBillNo());
            notifyRequest.setTransStatus(0);
            notifyRequest.setMsg("回调处理中");
            notifyRequest.setTransTime(System.currentTimeMillis());
            notifyRequest.setAmount(subjectInBills.getAmount());
            notifyRequest.setTransNo(transNo);
            notifyRequest.setMsg(resMessage);

            if ((subjectInBills.getStatus().intValue() == 0 || subjectInBills.getStatus().intValue() == 3)){
                if(StringUtils.isNotBlank(status)){
                    if(StringUtils.equals(UcfpayConstants.UCF_PAY_STATUS_SUCCESS,status)){
                        //支付成功
                        if(StringUtils.isNotBlank(tradeTime)){
                            notifyRequest.setTransTime(DateUtils.convert(tradeTime,DateUtils.DATE_TIMESTAMP_SHORT_FORMAT).getTime());
                        }else{
                            notifyRequest.setTransTime(System.currentTimeMillis());
                        }
                        notifyRequest.setTransStatus(1);
                        subjectInNotifyLog.setTransStatus(1);
                    }else if(StringUtils.equals(UcfpayConstants.UCF_PAY_STATUS_PROCESSING ,status)){
                        //支付处理中
                        notifyRequest.setTransStatus(0);
                        subjectInNotifyLog.setTransStatus(0);
                    }else if(StringUtils.equals(UcfpayConstants.UCF_PAY_STATUS_FAILURE ,status)){
                        //均为失败
                        notifyRequest.setTransStatus(2);
                        subjectInNotifyLog.setTransStatus(2);
                    }
                }else {
                    if(StringUtils.equals("00000",resCode)){
                        notifyRequest.setTransStatus(0);
                        subjectInNotifyLog.setTransStatus(0);
                    }else{
                        //均为失败
                        notifyRequest.setTransStatus(2);
                        subjectInNotifyLog.setTransStatus(2);
                    }
                    subjectInNotifyLog.setMsg("没有交易状态");
                }

                int transStatus = notifyRequest.getTransStatus().intValue();
                if (transStatus == 1 || transStatus == 2) {
                    //更新订单表状态
                    subjectInBills.setStatus(transStatus);
                    subjectInBillsService.updateById(subjectInBills);
                    try {
                        //TODO 回调支付中台
                        subjectPayNotifyUtil.notifyPay(subjectInBills.getSubjectCode(),"notify/protocolPay",notifyRequest);
                    }catch (Exception e){
                        log.error("回调支付中台异常，notifyRequest：{},error：{}",notifyRequest,e);
                    }
                }
            }else {
                subjectInNotifyLog.setMsg("订单状态已确定,不处理");
            }

            result ="SUCCESS";
        }else {
            //验签不通过
            //直接返回不处理业务
            subjectInNotifyLog.setStatus(2);
            subjectInNotifyLog.setMsg("先锋协议支付回调_验签不通过");
            log.error("先锋协议支付回调_验签失败,request:{}",request);
        }

        //记录通知第三方支付公司的信息
        subjectInNotifyLog.setResponseText(result);
        try {
            subjectInNotifyLogService.updateById(subjectInNotifyLog);
        }catch (Exception e){
            log.error("更新支付回调记录表失败,request:{},error:{}",request,e);
        }
        return result;
    }

    @Override
    public TransResult quickPayApply(TransRequest request) {
        TransResult transResult = new TransResult();
        transResult.setBillNo(request.getBillNo());
        transResult.setMerchantBillNo(request.getMerchantBillNo());
        transResult.setAmount(request.getAmount());
        transResult.setTransStatus(0);
        transResult.setTransTime(System.currentTimeMillis());

        String category=request.getChannelCode().getCode();

        String merchantNo=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.MERCHANTNO.getName());
        String requestUrl=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.REQUESTURL.getName());
        String privateKey=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.PRIVATEKEY.getName());
        String publicKey=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.PUBLICKEY.getName());
        String callBackUrl=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.CALLBACKURL.getName());
        String MD5Key=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.MD5KEY.getName());

        if(StringUtils.isBlank(requestUrl) || StringUtils.isBlank(merchantNo) || StringUtils.isBlank(privateKey) || StringUtils.isBlank(publicKey) || StringUtils.isBlank(callBackUrl) || StringUtils.isBlank(MD5Key)){
            transResult.setTransStatus(2);
            transResult.setMsg(ErrorMsg.INCOMPLETE_CONFIG_INFO);
            return transResult;
        }

        Map<String,String>  params = this.createHeadParams("REQ_PAY_QUICK_APPLY",merchantNo);
        //data加密 //获取加密的业务数据map集合
        Map<String,String> dataParams  = this.getQuickPayEncryptData(request,callBackUrl);
        //对业务数据进行加密
        String data = this.encryptData(dataParams,publicKey).toString();
        params.put("data",data);
        //对头、业务数据进行签名
        String signData = this.signData(params,publicKey).toString();
        params.put("sign",signData);

        MultiValueMap<String, String> postParameters = new LinkedMultiValueMap<String, String>();
        for(String key : params.keySet()){
            postParameters.add(key,params.get(key));
        }

        SubjectInThirdBills subjectInThirdBills=new SubjectInThirdBills();
        subjectInThirdBills.setSubjectCode(request.getSubjectCode());
        subjectInThirdBills.setMerchantBillNo(request.getMerchantBillNo());
        subjectInThirdBills.setBillNo(request.getBillNo());
        subjectInThirdBills.setStatus(0);
        subjectInThirdBills.setAmount(request.getAmount());
        subjectInThirdBills.setRequestUrl(requestUrl);
        subjectInThirdBills.setRequestText(JSON.toJSONString(postParameters));
        subjectInThirdBills.setBeginTime(System.currentTimeMillis());
        subjectInThirdBills.setServiceType(request.getServiceType());

        String str = null;
        try {
            str = restTemplate.postForObject(requestUrl,postParameters,String.class);
            str = AESCoder.decrypt(str, publicKey);
        } catch (Exception e) {
            log.error("调用先锋快捷支付接口异常,billNo:{},error:{}",request.getBillNo(),e);
            transResult.setMsg(ErrorMsg.PAY_INTERFACE_CALL_FAIL);
        }

        subjectInThirdBills.setResponseText((StringUtils.isNotBlank(str) && str.length()>4000)?str.substring(0,4000):str);
        subjectInThirdBills.setEndTime(System.currentTimeMillis());

        if (StringUtils.isBlank(str)) {
            //默认交易处理中
            log.error("调用先锋快捷接口返回空,billNo:{}",request.getBillNo());
            transResult.setMsg(ErrorMsg.PAY_INTERFACE_RETURN_BLANK);
        }else {
            JSONObject jsonObject = JSON.parseObject(str);
            String result_code = jsonObject.getString("resCode");
            String result_msg = jsonObject.getString("resMessage");
            String trans_no = jsonObject.getString("tradeNo");
            String status = jsonObject.getString("status");
            //交易完成时间
            String tradeTime = jsonObject.getString("tradeTime");

            if(StringUtils.isNotBlank(tradeTime)){
                transResult.setTransTime(DateUtils.convert(tradeTime,DateUtils.DATE_TIMESTAMP_SHORT_FORMAT).getTime());
            }else{
                transResult.setTransTime(System.currentTimeMillis());
            }
            transResult.setTransNo(trans_no);
            transResult.setMsg(result_msg);

            //以status为准来判断订单状态
            if (StringUtils.isNotBlank(status)) {
                if (StringUtils.equals(UcfpayConstants.UCF_PAY_STATUS_SUCCESS, status)) {
                    //交易成功
                    transResult.setTransStatus(1);
                    subjectInThirdBills.setStatus(1);
                } else if (StringUtils.equals(UcfpayConstants.UCF_PAY_STATUS_PROCESSING, status)) {
                    //处理中
                    transResult.setTransStatus(0);
                    subjectInThirdBills.setStatus(0);
                } else if (StringUtils.equals(UcfpayConstants.UCF_PAY_STATUS_FAILURE, status)) {
                    //失败
                    transResult.setTransStatus(2);
                    subjectInThirdBills.setStatus(2);
                }
            } else {
                if(StringUtils.equals("00000",result_code)){
                    transResult.setTransStatus(0);
                    subjectInThirdBills.setStatus(0);
                }else{
                    transResult.setTransStatus(2);
                    subjectInThirdBills.setStatus(2);
                }
            }
        }

        try {
            subjectInThirdBillsService.insert(subjectInThirdBills);
        } catch (Exception e) {
            log.error("插入第三方订单表异常,billNo:{},error:{}",request.getBillNo(),e);
        }

        return transResult;
    }

    @Override
    public TransResult quickPayConfirm(TransRequest request) {
        TransResult transResult = new TransResult();
        transResult.setBillNo(request.getBillNo());
        transResult.setMerchantBillNo(request.getMerchantBillNo());
        transResult.setAmount(request.getAmount());
        transResult.setTransStatus(0);
        transResult.setTransTime(System.currentTimeMillis());

        String category=request.getChannelCode().getCode();

        String merchantNo=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.MERCHANTNO.getName());
        String requestUrl=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.REQUESTURL.getName());
        String privateKey=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.PRIVATEKEY.getName());
        String publicKey=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.PUBLICKEY.getName());
        String callBackUrl=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.CALLBACKURL.getName());
        String MD5Key=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.MD5KEY.getName());

        if(StringUtils.isBlank(requestUrl) || StringUtils.isBlank(merchantNo) || StringUtils.isBlank(privateKey) || StringUtils.isBlank(publicKey) || StringUtils.isBlank(callBackUrl) || StringUtils.isBlank(MD5Key)){
            transResult.setTransStatus(2);
            transResult.setMsg(ErrorMsg.INCOMPLETE_CONFIG_INFO);
            return transResult;
        }

        Map<String,String>  params = this.createHeadParams("REQ_PAY_QUICK_CONFIRM",merchantNo);
        Map<String, String> pdata = new LinkedHashMap<>();
        pdata.put("merchantNo", request.getBillNo());
        pdata.put("checkCode", request.getSmsCode());
        //对业务数据进行加密
        String data = this.encryptData(pdata,publicKey).toString();
        params.put("data",data);
        //对头、业务数据进行签名
        String signData = this.signData(params,publicKey).toString();
        params.put("sign",signData);

        MultiValueMap<String, String> postParameters = new LinkedMultiValueMap<String, String>();
        for(String key : params.keySet()){
            postParameters.add(key,params.get(key));
        }

        SubjectInThirdBills subjectInThirdBills=new SubjectInThirdBills();
        subjectInThirdBills.setSubjectCode(request.getSubjectCode());
        subjectInThirdBills.setMerchantBillNo(request.getMerchantBillNo());
        subjectInThirdBills.setBillNo(request.getBillNo());
        subjectInThirdBills.setStatus(0);
        subjectInThirdBills.setAmount(request.getAmount());
        subjectInThirdBills.setRequestUrl(requestUrl);
        subjectInThirdBills.setRequestText(JSON.toJSONString(postParameters));
        subjectInThirdBills.setBeginTime(System.currentTimeMillis());
        subjectInThirdBills.setServiceType(request.getServiceType());

        String str = null;
        try {
            str = restTemplate.postForObject(requestUrl,postParameters,String.class);
            str = AESCoder.decrypt(str, publicKey);
        } catch (Exception e) {
            log.error("调用先锋快捷支付确认接口异常,billNo:{},error:{}",request.getBillNo(),e);
            transResult.setMsg(ErrorMsg.PAY_INTERFACE_CALL_FAIL);
        }

        subjectInThirdBills.setResponseText((StringUtils.isNotBlank(str) && str.length()>4000)?str.substring(0,4000):str);
        subjectInThirdBills.setEndTime(System.currentTimeMillis());

        if (StringUtils.isBlank(str)) {
            //默认交易处理中
            log.error("调用先锋快捷支付确认接口返回空,billNo:{}",request.getBillNo());
            transResult.setMsg(ErrorMsg.PAY_INTERFACE_RETURN_BLANK);
        }else {
            JSONObject jsonObject = JSON.parseObject(str);
            String result_code = jsonObject.getString("resCode");
            String result_msg = jsonObject.getString("resMessage");
            String trans_no = jsonObject.getString("tradeNo");
            String status = jsonObject.getString("status");
            //交易完成时间
            String tradeTime = jsonObject.getString("tradeTime");

            if(StringUtils.isNotBlank(tradeTime)){
                transResult.setTransTime(DateUtils.convert(tradeTime,DateUtils.DATE_TIMESTAMP_SHORT_FORMAT).getTime());
            }else{
                transResult.setTransTime(System.currentTimeMillis());
            }
            transResult.setTransNo(trans_no);
            transResult.setMsg(result_msg);

            //以status为准来判断订单状态
            if (StringUtils.isNotBlank(status)) {
                if (StringUtils.equals(UcfpayConstants.UCF_PAY_STATUS_SUCCESS, status)) {
                    //交易成功
                    transResult.setTransStatus(1);
                    subjectInThirdBills.setStatus(1);
                } else if (StringUtils.equals(UcfpayConstants.UCF_PAY_STATUS_PROCESSING, status)) {
                    //处理中
                    //TODO 如果是验证码不正确的情况，置为失败
                    if(StringUtils.equals(result_code,"20005")){
                        transResult.setTransStatus(2);
                        subjectInThirdBills.setStatus(2);
                        transResult.setMsg(ErrorMsg.SMSCODE_FAIL);
                    }else {
                        transResult.setTransStatus(0);
                        subjectInThirdBills.setStatus(0);
                    }
                } else if (StringUtils.equals(UcfpayConstants.UCF_PAY_STATUS_FAILURE, status)) {
                    //失败
                    transResult.setTransStatus(2);
                    subjectInThirdBills.setStatus(2);
                }
            } else {
                if(StringUtils.equals("00000",result_code)){
                    transResult.setTransStatus(0);
                    subjectInThirdBills.setStatus(0);
                }else{
                    transResult.setTransStatus(2);
                    subjectInThirdBills.setStatus(2);
                }
            }
        }

        try {
            subjectInThirdBillsService.insert(subjectInThirdBills);
        } catch (Exception e) {
            log.error("插入第三方订单表异常,billNo:{},error:{}",request.getBillNo(),e);
        }

        return transResult;
    }

    @Override
    public TransResult quickPayReSendSMS(TransRequest request) {
        TransResult transResult = new TransResult();
        transResult.setBillNo(request.getBillNo());
        transResult.setMerchantBillNo(request.getMerchantBillNo());
        transResult.setAmount(request.getAmount());
        transResult.setTransStatus(0);
        transResult.setTransTime(System.currentTimeMillis());

        String category=request.getChannelCode().getCode();

        String merchantNo=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.MERCHANTNO.getName());
        String requestUrl=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.REQUESTURL.getName());
        String privateKey=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.PRIVATEKEY.getName());
        String publicKey=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.PUBLICKEY.getName());
        String callBackUrl=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.CALLBACKURL.getName());
        String MD5Key=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.MD5KEY.getName());

        if(StringUtils.isBlank(requestUrl) || StringUtils.isBlank(merchantNo) || StringUtils.isBlank(privateKey) || StringUtils.isBlank(publicKey) || StringUtils.isBlank(callBackUrl) || StringUtils.isBlank(MD5Key)){
            transResult.setTransStatus(2);
            transResult.setMsg(ErrorMsg.INCOMPLETE_CONFIG_INFO);
            return transResult;
        }

        Map<String,String>  params = this.createHeadParams("REQ_PAY_QUICK_RESEND",merchantNo);
        params.put("merchantNo",request.getBillNo());
        //对头、业务数据进行签名
        String signData = this.signData(params,publicKey).toString();
        params.put("sign",signData);

        MultiValueMap<String, String> postParameters = new LinkedMultiValueMap<String, String>();
        for(String key : params.keySet()){
            postParameters.add(key,params.get(key));
        }

        SubjectInThirdBills subjectInThirdBills=new SubjectInThirdBills();
        subjectInThirdBills.setSubjectCode(request.getSubjectCode());
        subjectInThirdBills.setMerchantBillNo(request.getMerchantBillNo());
        subjectInThirdBills.setBillNo(request.getBillNo());
        subjectInThirdBills.setStatus(0);
        subjectInThirdBills.setAmount(request.getAmount());
        subjectInThirdBills.setRequestUrl(requestUrl);
        subjectInThirdBills.setRequestText(JSON.toJSONString(postParameters));
        subjectInThirdBills.setBeginTime(System.currentTimeMillis());
        subjectInThirdBills.setServiceType(request.getServiceType());

        String str = null;
        try {
            str = restTemplate.postForObject(requestUrl,postParameters,String.class);
            str = AESCoder.decrypt(str, publicKey);
        } catch (Exception e) {
            log.error("调用先锋快捷支付重发短信验证码接口异常,billNo:{},error:{}",request.getBillNo(),e);
            transResult.setMsg(ErrorMsg.PAY_INTERFACE_CALL_FAIL);
        }

        subjectInThirdBills.setResponseText((StringUtils.isNotBlank(str) && str.length()>4000)?str.substring(0,4000):str);
        subjectInThirdBills.setEndTime(System.currentTimeMillis());

        if (StringUtils.isBlank(str)) {
            //默认交易处理中
            log.error("调用先锋快捷支付重发短信验证码接口返回空,billNo:{}",request.getBillNo());
            transResult.setMsg(ErrorMsg.PAY_INTERFACE_RETURN_BLANK);
        }else {
            JSONObject jsonObject = JSON.parseObject(str);
            String result_code = jsonObject.getString("resCode");
            String result_msg = jsonObject.getString("resMessage");

            transResult.setMsg(result_msg);

            if(StringUtils.isNotBlank(result_code)) {
                if (StringUtils.equals("00000", result_code)) {
                    //成功
                    transResult.setTransStatus(1);
                    subjectInThirdBills.setStatus(1);
                }else {
                    //失败
                    transResult.setTransStatus(2);
                    subjectInThirdBills.setStatus(2);
                }
            }else {
                //失败
                transResult.setTransStatus(2);
                subjectInThirdBills.setStatus(2);
            }
        }

        try {
            subjectInThirdBillsService.insert(subjectInThirdBills);
        } catch (Exception e) {
            log.error("插入第三方订单表异常,billNo:{},error:{}",request.getBillNo(),e);
        }

        return transResult;
    }

    @Override
    public TransResult quickPayQuery(SubjectpayQueryRequest request) {
        TransResult transResult = new TransResult();
        transResult.setBillNo(request.getBillNo());
        transResult.setMerchantBillNo(request.getMerchantBillNo());
        transResult.setAmount(request.getAmount());
        transResult.setTransStatus(0);
        transResult.setTransTime(System.currentTimeMillis());

        String category=request.getChannelCode();

        String merchantNo=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.MERCHANTNO.getName());
        String requestUrl=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.REQUESTURL.getName());
        String privateKey=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.PRIVATEKEY.getName());
        String publicKey=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.PUBLICKEY.getName());
        String callBackUrl=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.CALLBACKURL.getName());
        String MD5Key=subjectChannelConfigService.getConfigString(category,ConfigKeyEnums.MD5KEY.getName());

        if(StringUtils.isBlank(requestUrl) || StringUtils.isBlank(merchantNo) || StringUtils.isBlank(privateKey) || StringUtils.isBlank(publicKey) || StringUtils.isBlank(callBackUrl) || StringUtils.isBlank(MD5Key)){
            transResult.setTransStatus(2);
            transResult.setMsg(ErrorMsg.INCOMPLETE_CONFIG_INFO);
            return transResult;
        }

        Map<String,String>  params = this.createHeadParams("REQ_QUICK_QUERY_BY_ID",merchantNo);
        params.put("merchantNo",request.getBillNo());
        //对头、业务数据进行签名
        String signData = this.signData(params,publicKey).toString();
        params.put("sign",signData);

        MultiValueMap<String, String> postParameters = new LinkedMultiValueMap<String, String>();
        for(String key : params.keySet()){
            postParameters.add(key,params.get(key));
        }

        SubjectInThirdBills subjectInThirdBills=new SubjectInThirdBills();
        subjectInThirdBills.setSubjectCode(request.getSubjectCode());
        subjectInThirdBills.setMerchantBillNo(request.getMerchantBillNo());
        subjectInThirdBills.setBillNo(request.getBillNo());
        subjectInThirdBills.setStatus(0);
        subjectInThirdBills.setAmount(request.getAmount());
        subjectInThirdBills.setRequestUrl(requestUrl);
        subjectInThirdBills.setRequestText(JSON.toJSONString(postParameters));
        subjectInThirdBills.setBeginTime(System.currentTimeMillis());
        subjectInThirdBills.setServiceType(request.getServiceType());

        String str = null;
        try {
            str = restTemplate.postForObject(requestUrl,postParameters,String.class);
            str = AESCoder.decrypt(str, publicKey);
        } catch (Exception e) {
            log.error("调用先锋快捷支付查询接口异常,billNo:{},error:{}",request.getBillNo(),e);
            transResult.setMsg(ErrorMsg.PAY_INTERFACE_CALL_FAIL);
        }

        subjectInThirdBills.setResponseText((StringUtils.isNotBlank(str) && str.length()>4000)?str.substring(0,4000):str);
        subjectInThirdBills.setEndTime(System.currentTimeMillis());

        if (StringUtils.isBlank(str)) {
            //默认交易处理中
            log.error("调用先锋快捷支付查询接口返回空,billNo:{}",request.getBillNo());
            transResult.setMsg(ErrorMsg.PAY_INTERFACE_RETURN_BLANK);
        }else {
            JSONObject jsonObject = JSON.parseObject(str);
            String result_code = jsonObject.getString("resCode");
            String result_msg = jsonObject.getString("resMessage");
            String trans_no = jsonObject.getString("tradeNo");
            String status = jsonObject.getString("status");
            //交易完成时间
            String tradeTime = jsonObject.getString("tradeTime");

            if(StringUtils.isNotBlank(tradeTime)){
                transResult.setTransTime(DateUtils.convert(tradeTime,DateUtils.DATE_TIMESTAMP_SHORT_FORMAT).getTime());
            }else{
                transResult.setTransTime(System.currentTimeMillis());
            }
            transResult.setTransNo(trans_no);
            transResult.setMsg(result_msg);

            //以status为准来判断订单状态
            if (StringUtils.isNotBlank(status)) {
                if (StringUtils.equals(UcfpayConstants.UCF_PAY_STATUS_SUCCESS, status)) {
                    //交易成功
                    transResult.setTransStatus(1);
                    subjectInThirdBills.setStatus(1);
                } else if (StringUtils.equals(UcfpayConstants.UCF_PAY_STATUS_PROCESSING, status)) {
                    //处理中
                    transResult.setTransStatus(0);
                    subjectInThirdBills.setStatus(0);
                } else if (StringUtils.equals(UcfpayConstants.UCF_PAY_STATUS_FAILURE, status)) {
                    //失败
                    transResult.setTransStatus(2);
                    subjectInThirdBills.setStatus(2);
                }
            } else {
                if(StringUtils.equals("00000",result_code)){
                    transResult.setTransStatus(0);
                    subjectInThirdBills.setStatus(0);
                }else{
                    transResult.setTransStatus(2);
                    subjectInThirdBills.setStatus(2);
                }
            }
        }

        try {
            subjectInThirdBillsService.insert(subjectInThirdBills);
        } catch (Exception e) {
            log.error("先锋协议支付插入第三方订单表异常,billNo:{},error:{}",request.getBillNo(),e);
        }

        return transResult;
    }

    @Override
    public String quickPayNotify(CallbackRequest request) {
        String result ="";

        //记录回调原始数据
        SubjectInNotifyLog subjectInNotifyLog = new SubjectInNotifyLog();
        subjectInNotifyLog.setCallbackText(JSONObject.toJSONString(request));
        //默认回调处理状态为处理中
        subjectInNotifyLog.setStatus(0);
        //默认订单交易状态为处理中
        subjectInNotifyLog.setTransStatus(0);
        subjectInNotifyLog.setCallbackText(request.getData());
        subjectInNotifyLog.setMsg("回调处理中");
        boolean rt = subjectInNotifyLogService.insert(subjectInNotifyLog);
        if (!rt){
            log.error("插入回调日志表失败,request:{}",request);
            return result;
        }

        String publicKey=subjectChannelConfigService.getConfigString(ChannelCode.CH2222221.getCode(),ConfigKeyEnums.PUBLICKEY.getName());

        String enData = request.getData();
        String dataStr = null;
        try {
            dataStr = AESCoder.decrypt(enData , publicKey);
        }catch (Exception e){
            log.error("先锋快捷支付回调数据前为："+ request.getData() +" 】 【处理后为："+enData);
            log.error("先锋快捷支付数据解密时出错",e);
        }

        subjectInNotifyLog.setCallbackText(dataStr);

        JSONObject data = JSONObject.parseObject(dataStr);
        //保存签名值
        String signValue = "";
        //保存参与验签字段
        Map<String,String> signParameters = new HashMap<String,String>();
        if(null != data){
            Iterator iterator = data.keySet().iterator();
            while(iterator.hasNext()){
                String key = iterator.next().toString();
                String value = data.getString(key);
                if(StringUtils.equals( UcfpayConstants.SIGN,key)){
                    signValue = value;
                }else{
                    signParameters.put(key, value);
                }
            }

        }
        boolean verifyResult = false;
        try{
            verifyResult = UcfForOnline.verify(publicKey, UcfpayConstants.SIGN, signValue, signParameters,  UcfpayConstants.SECID);
        }catch (Exception e){
            log.error("调用先锋协议支付类库中验签方法异常！");
        }

        if(verifyResult){
            String resCode = signParameters.get("resCode");
            String resMessage = signParameters.get("resMessage");
            //订单支付状态：S成功，F 失败
            String status = signParameters.get("status");
            String transNo = signParameters.get("tradeNo");
            String billNo = signParameters.get("merchantNo");
            //交易完成时间 要转换
            String tradeTime = signParameters.get("tradeTime");

            //查询回调对应的订单信息
            SubjectInBills subjectInBillsFind = new SubjectInBills();
            subjectInBillsFind.setBillNo(billNo);
            SubjectInBills subjectInBills = subjectInBillsService.getLastOneInBills(subjectInBillsFind);
            if(null==subjectInBills){
                log.error("未查询到该笔订单,request:{}",request);
                return result;
            }
            subjectInNotifyLog.setBillNo(billNo);
            subjectInNotifyLog.setSubjectCode(subjectInBills.getSubjectCode());
            subjectInNotifyLog.setMerchantBillNo(subjectInBills.getMerchantBillNo());
            subjectInNotifyLog.setStatus(1);
            subjectInNotifyLog.setTransNo(transNo);
            subjectInNotifyLog.setMsg(resMessage);

            //转发到支付中台的回调对象
            NotifyRequest notifyRequest=new NotifyRequest();
            notifyRequest.setMerchantBillNo(subjectInBills.getMerchantBillNo());
            notifyRequest.setBillNo(subjectInBills.getBillNo());
            notifyRequest.setTransStatus(0);
            notifyRequest.setMsg("回调处理中");
            notifyRequest.setTransTime(System.currentTimeMillis());
            notifyRequest.setAmount(subjectInBills.getAmount());
            notifyRequest.setTransNo(transNo);
            notifyRequest.setMsg(resMessage);

            if ((subjectInBills.getStatus().intValue() == 0 || subjectInBills.getStatus().intValue() == 3)){
                if(StringUtils.isNotBlank(status)){
                    if(StringUtils.equals(UcfpayConstants.UCF_PAY_STATUS_SUCCESS,status)){
                        //支付成功
                        if(StringUtils.isNotBlank(tradeTime)){
                            notifyRequest.setTransTime(DateUtils.convert(tradeTime,DateUtils.DATE_TIMESTAMP_SHORT_FORMAT).getTime());
                        }else{
                            notifyRequest.setTransTime(System.currentTimeMillis());
                        }
                        notifyRequest.setTransStatus(1);
                        subjectInNotifyLog.setTransStatus(1);
                    }else if(StringUtils.equals(UcfpayConstants.UCF_PAY_STATUS_PROCESSING ,status)){
                        //支付处理中
                        notifyRequest.setTransStatus(0);
                        subjectInNotifyLog.setTransStatus(0);
                    }else if(StringUtils.equals(UcfpayConstants.UCF_PAY_STATUS_FAILURE ,status)){
                        //均为失败
                        notifyRequest.setTransStatus(2);
                        subjectInNotifyLog.setTransStatus(2);
                    }
                }else {
                    if(StringUtils.equals("00000",resCode)){
                        notifyRequest.setTransStatus(0);
                        subjectInNotifyLog.setTransStatus(0);
                    }else{
                        //均为失败
                        notifyRequest.setTransStatus(2);
                        subjectInNotifyLog.setTransStatus(2);
                    }
                    subjectInNotifyLog.setMsg("没有交易状态");
                }

                int transStatus = notifyRequest.getTransStatus().intValue();
                if (transStatus == 1 || transStatus == 2) {
                    //更新订单表状态
                    subjectInBills.setStatus(transStatus);
                    subjectInBillsService.updateById(subjectInBills);
                    try {
                        //TODO 回调支付中台
                        subjectPayNotifyUtil.notifyPay(subjectInBills.getSubjectCode(),"notify/quickPay",notifyRequest);
                    }catch (Exception e){
                        log.error("回调支付中台异常，notifyRequest：{},error：{}",notifyRequest,e);
                    }
                }
            }else {
                subjectInNotifyLog.setMsg("订单状态已确定,不处理");
            }

            result ="SUCCESS";
        }else {
            //验签不通过
            //直接返回不处理业务
            subjectInNotifyLog.setStatus(2);
            subjectInNotifyLog.setMsg("先锋协议支付回调_验签不通过");
            log.error("先锋协议支付回调_验签失败,request:{}",request);
        }

        //记录通知第三方支付公司的信息
        subjectInNotifyLog.setResponseText(result);
        try {
            subjectInNotifyLogService.updateById(subjectInNotifyLog);
        }catch (Exception e){
            log.error("更新支付回调记录表失败,request:{},error:{}",request,e);
        }
        return result;
    }

    /** 获取请求头参数
     * @param service 服务类型
     * @param merId 商户号
     * @return
     */
    private Map<String, String> createHeadParams(String service,String merId) {
        Map<String, String> params = new HashMap<String, String>();
        params.put("service", service);
        params.put("secId", UcfpayConstants.SECID);
        params.put("version",UcfpayConstants.VERSION);
        String reqSn=UUID.randomUUID().toString().replaceAll("-","");
        params.put("reqSn", reqSn);
        params.put("merchantId",merId);
        return params;
    }

    /** 获取签约绑卡请求数据
     * @param request
     * @return
     */
    private Map<String,String> getBindCardEncryptData(BindCardDto request){
        //银行卡签约加密业务字段
        Map<String,String> dataParams = new LinkedHashMap<String,String>();
        //商户订单号  对应系统中billNo
        dataParams.put("merchantNo",request.getBillNo());
        dataParams.put("accountNo",request.getCardNo());
        dataParams.put("accountName",request.getName());
        //0（身份证）
        dataParams.put("certificateType",UcfpayConstants.ID_CARD);
        dataParams.put("certificateNo",request.getIdCard());
        dataParams.put("mobileNo",request.getPhone());
        dataParams.put("memo","");
        return  dataParams;
    }

    private Map<String,String> getProtocolPayEncryptData(TransRequest request,String noticeUrl){
        //将内部代码转换为先锋的银行代码
        UcfpayDsBankCode ucfpayDsBankCode = ucfpayDsBankCodeService.getBankCode(request.getCardBin());
        String bankId = ucfpayDsBankCode.getBankCode();

        //加密业务字段
        Map<String,String> dataParams = new LinkedHashMap<String,String>();
        //商户订单号  对应系统中billNo
        dataParams.put("merchantNo",request.getBillNo());
        String ucf_amt = String.valueOf(request.getAmount().multiply(BigDecimal.valueOf(100)).setScale(0, BigDecimal.ROUND_HALF_UP));
        dataParams.put("contractNo",request.getProtocolNo());
        //金额（分）
        dataParams.put("amount",ucf_amt);
        //币种 默认：人民币
        dataParams.put("transCur",UcfpayConstants.CURRENCY_RMB);
        //商户传入固定值：1（对私）。
        dataParams.put("userType","1");
        //由先锋支付定义，商户传入指定值：1（借记卡）2（贷记卡）
        dataParams.put("accountType","1");
        //0（身份证）
        dataParams.put("certificateType",UcfpayConstants.ID_CARD);
        dataParams.put("certificateNo",request.getIdCard());
        dataParams.put("accountNo",request.getCardNo());
        dataParams.put("accountName",request.getName());
        dataParams.put("cvn2","");
        dataParams.put("validDate","");
        dataParams.put("mobileNo",request.getPhone());
        //银行编码
        dataParams.put("bankId",bankId);
        //银行名称
        dataParams.put("bankName",ucfpayDsBankCode.getBankName());
        dataParams.put("productInfo","消费");
        dataParams.put("productName","商品");
        //后台通知地址
        dataParams.put("noticeUrl",noticeUrl);
        String expireTime= this.getDateTime();
        dataParams.put("expireTime",expireTime);
        dataParams.put("memo","");
        return  dataParams;
    }

    private Map<String,String> getQuickPayEncryptData(TransRequest request,String noticeUrl){
        //将内部代码转换为先锋的银行代码
        UcfpayDsBankCode ucfpayDsBankCode = ucfpayDsBankCodeService.getBankCode(request.getCardBin());
        String bankId = ucfpayDsBankCode.getBankCode();

        //加密业务字段
        Map<String,String> dataParams = new LinkedHashMap<String,String>();
        //商户订单号  对应系统中billNo
        dataParams.put("merchantNo",request.getBillNo());
        dataParams.put("payerId","");
        //金额（分）
        String ucf_amt = String.valueOf(request.getAmount().multiply(BigDecimal.valueOf(100)).setScale(0, BigDecimal.ROUND_HALF_UP));
        dataParams.put("amount",ucf_amt);
        //币种 默认：人民币
        dataParams.put("transCur",UcfpayConstants.CURRENCY_RMB);
        //0（身份证）
        dataParams.put("certificateType",UcfpayConstants.ID_CARD);
        dataParams.put("certificateNo",request.getIdCard());
        dataParams.put("accountNo",request.getCardNo());
        dataParams.put("accountName",request.getName());
        dataParams.put("cvn2","");
        dataParams.put("validDate","");
        dataParams.put("mobileNo",request.getPhone());
        //银行编码
        dataParams.put("bankId",bankId);
        //银行名称
        dataParams.put("bankName",ucfpayDsBankCode.getBankName());
        dataParams.put("productInfo","消费");
        dataParams.put("productName","商品");
        //后台通知地址
        dataParams.put("noticeUrl",noticeUrl);
        String expireTime=this.getDateTime();
        dataParams.put("expireTime",expireTime);
        dataParams.put("memo","");
        return  dataParams;
    }

    public String getDateTime() {
        //获取时间加 一天
        Date date = new Date();
        Calendar cal = Calendar.getInstance();
        //设置起时间
        cal.setTime(date);
        //增加一天
        cal.add(Calendar.DATE, 1);
        Date time=cal.getTime();
        return DateUtils.convert(time,DateUtils.DATE_TIME_FORMAT);
    }

    /**对业务数据进行加密
     * @param dataParams
     * @param merRSAKey
     * @return
     */
    private Object encryptData(Map<String,String> dataParams,String merRSAKey){
        //参与加密的业务字段
        JSONObject jsonObject =new JSONObject();
        //用于保存加密的业务字段
        String dataValue = "";
        Iterator dataIterator = dataParams.keySet().iterator();
        while (dataIterator.hasNext()){
            String key = dataIterator.next().toString();
            String values = dataParams.get(key);
            jsonObject.put(key,values);
        }
        //data加密
        try{
            dataValue = AESCoder.encrypt(jsonObject.toString(),merRSAKey);
        }catch (Exception e){
            log.error("先锋支付业务数据字段加密失败" + dataValue, e);
        }
        return dataValue;
    }

    /**签名
     * @param map
     * @param merRSAKey
     * @return
     */
    private Object signData(Map<String,String> map,String merRSAKey){
        Map<String, String> params = new LinkedHashMap<String, String>();//参与签名业务字段集合
        Iterator signIterator = map.keySet().iterator();
        String signValue = "";//用于保存签名字段
        while (signIterator.hasNext()){
            String key = signIterator.next().toString();
            String values = map.get(key).toString();
            if(!StringUtils.equals("sign",key) ){
                params.put(key,values);
            }
        }
        try {
            //调用先锋支付类库生成签名
            signValue = UcfForOnline.createSign(merRSAKey,UcfpayConstants.SIGN, params,UcfpayConstants.SECID);
            System.out.println("RsaCoder.encryptByPublicKey: "+signValue);
        } catch (Exception e) {
            log.error("先锋支付SIGN数据字段加密失败" + signValue, e);
        }
        return  signValue;
    }

}

